﻿<!doctype html>
<html lang="en">
	<head>
		<title>JavaScript Patterns</title>
		<meta charset="utf-8">
	</head>
	<body>
		<script>
			/* Title: Public and Private Static Members
			 Description:
			 Public Static Members - accessible outside the constructor
			 Private Static Members - shared by all the objects with the same constructor function and not accessible outside the constructor
			 */

			// Public Static Members

			// constructor
			var Gadget = function () {
			};

			// a static method
			Gadget.isShiny = function () {
				return "you bet";
			};

			// a normal method added to the prototype
			Gadget.prototype.setPrice = function (price) {
				this.price = price;
			};

			// calling a static method
			console.log(Gadget.isShiny()); // "you bet"

			// creating an instance and calling a method
			var iphone = new Gadget();
			iphone.setPrice(500);

			console.log(typeof Gadget.setPrice); // "undefined"
			console.log(typeof iphone.isShiny); // "undefined"

			Gadget.prototype.isShiny = Gadget.isShiny;
			console.log(iphone.isShiny()); // "you bet"


			// constructor
			var Gadget = function (price) {
				this.price = price;
			};

			// a static method
			Gadget.isShiny = function () {

				// this always works
				var msg = "you bet";

				if (this instanceof Gadget) {
					// this only works if called non-statically
					msg += ", it costs $" + this.price + '!';
				}

				return msg;
			};

			// a normal method added to the prototype
			Gadget.prototype.isShiny = function () {
				return Gadget.isShiny.call(this);
			};

			console.log(Gadget.isShiny()); // "you bet"

			var a = new Gadget('499.99');
			console.log(a.isShiny()); // "you bet, it costs $499.99!"


			// Private Static Members

			// method 1
			var Gadget = (function () {

				// static variable/property
				var counter = 0;

				// returning the new implementation
				// of the constructor
				return function () {
					console.log(counter += 1);
				};
			}()); // execute immediately

			var g1 = new Gadget(); // logs 1
			var g2 = new Gadget(); // logs 2
			var g3 = new Gadget(); // logs 3


			// method 2
			var Gadget = (function () {

				// static variable/property
				var counter = 0,
						NewGadget;

				// this will become the
				// new constructor implementation
				NewGadget = function () {
					counter += 1;
				};

				// a priviledged method
				NewGadget.prototype.getLastId = function () {
					return counter;
				};

				// overwrite the constructor
				return NewGadget;

			}()); // execute immediately

			var iphone = new Gadget();
			iphone.getLastId(); // 1
			var ipod = new Gadget();
			ipod.getLastId(); // 2
			var ipad = new Gadget();
			ipad.getLastId(); // 3
		</script>
	</body>
</html>